package edu.zcmu.seckill.interceptor;

import com.alibaba.fastjson.JSON;
import edu.zcmu.seckill.exception.MyException;
import edu.zcmu.seckill.response.ResultCode;
import edu.zcmu.seckill.utils.IpAdrressUtil;
import edu.zcmu.seckill.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @package: edu.zcmu.seckill.interceptor
 * @className: IpUrlLimitInterceptor
 * @description: ip+url重复请求现在拦截器
 **/
@Slf4j
@Component
public class IpUrlLimitInterceptor implements HandlerInterceptor {

    @Autowired
    RedisUtil redisUtil;

    private static final String LOCK_IP_URL_KEY="lock_ip_";

    private static final String IP_URL_REQ_TIME="ip_url_times_";

    private static final long LIMIT_TIMES=10;//每2秒LIMIT_TIMES次访问将被禁用

    private static final int IP_LOCK_TIME=60;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (ipIsLock(IpAdrressUtil.getIpAddress(request))){
            log.info("ip访问被禁止={}",IpAdrressUtil.getIpAddress(request));
            throw new MyException(ResultCode.ERROR,"禁止访问");
        }
        if(!addRequestTime(IpAdrressUtil.getIpAddress(request),request.getRequestURI())){
            throw new MyException(ResultCode.ERROR,"禁止访问");
        }
        return true;

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
    /**
     * @Description: 判断ip是否被禁用
     */
    private Boolean ipIsLock(String ip){

        if(redisUtil.hasKey(LOCK_IP_URL_KEY+ip)){
            return true;
        }
        return false;
    }
    /**
     * @Description: 记录请求次数
     */
    private Boolean addRequestTime(String ip,String uri){
        String key=IP_URL_REQ_TIME+ip+uri;
        if (redisUtil.hasKey(key)){
            long time=redisUtil.incr(key,(long)1);
            if (time>=LIMIT_TIMES){
                redisUtil.getLock(LOCK_IP_URL_KEY+ip,ip,IP_LOCK_TIME);
                return false;
            }
        }else {
            redisUtil.getLock(key,"1",2);//放置一个2秒过期的key
        }
        return true;
    }

}
